import { _decorator, Component, director, instantiate, Node, Prefab } from "cc";
import { ApiMsgEnum } from "../Common";
import { IApiPlayerListRes, IApiRoomListRes } from "../Common/Api";
import { IMsgPlayerList, IMsgRoomList } from "../Common/Msg";
import { EventEnum, SceneEnum } from "../Enum";
import DataManager from "../Global/DataManager";
import EventManager from "../Global/EventManager";
import { NetworkManager } from "../Global/NetworkManager";
import { PlayerManager } from "../UI/PlayerManager";
import { RoomManager } from "../UI/RoomManager";
const { ccclass, property } = _decorator;

@ccclass("HallManager")
export class HallManager extends Component {
    @property(Node)
    playerContiner: Node;
    @property(Prefab)
    playerPrefab: Prefab;
    @property(Node)
    roomContiner: Node;
    @property(Prefab)
    roomPrefab: Prefab;

    onLoad() {
        EventManager.Instance.on(EventEnum.RoomJoin, this.handleRoomJoin, this);
        NetworkManager.Instance.listenMsg(
            ApiMsgEnum.MsgPlayerList,
            this.renderPlayer,
            this
        );
        NetworkManager.Instance.listenMsg(
            ApiMsgEnum.MsgRoomList,
            this.renderRoom,
            this
        );
    }

    start() {
        this.playerContiner.destroyAllChildren();
        this.roomContiner.destroyAllChildren();
        this.getPlayers();
        this.getRooms();
    }

    protected onDestroy(): void {
        EventManager.Instance.off(
            EventEnum.RoomJoin,
            this.handleRoomJoin,
            this
        );
        NetworkManager.Instance.unlistenMsg(
            ApiMsgEnum.MsgPlayerList,
            this.renderPlayer,
            this
        );
        NetworkManager.Instance.unlistenMsg(
            ApiMsgEnum.MsgRoomList,
            this.renderRoom,
            this
        );
    }

    async getPlayers() {
        const { success, res, error } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiPlayerList,
            {}
        );
        if (!success) {
            console.log(error);
            return;
        }

        this.renderPlayer(res);
    }

    renderPlayer({ list }: IApiPlayerListRes | IMsgPlayerList) {
        for (const node of this.playerContiner.children) {
            node.active = false;
        }

        while (this.playerContiner.children.length < list.length) {
            const node = instantiate(this.playerPrefab);
            node.setParent(this.playerContiner);
            node.active = false;
        }

        for (let i = 0; i < list.length; i++) {
            const data = list[i];
            const node = this.playerContiner.children[i];
            const pm = node.getComponent(PlayerManager);
            pm.init(data);
        }
    }

    async getRooms() {
        const { success, res, error } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomList,
            {}
        );
        if (!success) {
            console.log(error);
            return;
        }

        this.renderRoom(res);
    }

    renderRoom({ list }: IApiRoomListRes | IMsgRoomList) {
        for (const node of this.roomContiner.children) {
            node.active = false;
        }

        while (this.roomContiner.children.length < list.length) {
            const node = instantiate(this.roomPrefab);
            node.setParent(this.roomContiner);
            node.active = false;
        }

        for (let i = 0; i < list.length; i++) {
            const data = list[i];
            const node = this.roomContiner.children[i];
            const pm = node.getComponent(RoomManager);
            pm.init(data);
        }
    }

    async handleCreateRoom() {
        const { success, res, error } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomCreate,
            {}
        );
        if (!success) {
            console.log(error);
            return;
        }

        DataManager.Instance.roomInfo = res.room;
        console.log("房间信息：", DataManager.Instance.roomInfo);
        director.loadScene(SceneEnum.Room);
    }

    async handleRoomJoin(rid: number) {
        const { success, res, error } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomJoin,
            { rid }
        );
        if (!success) {
            console.log(error);
            return;
        }

        DataManager.Instance.roomInfo = res.room;
        console.log("房间信息：", DataManager.Instance.roomInfo);
        director.loadScene(SceneEnum.Room);
    }
}
